package com.weibo.framework.core.concurrent;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ForkJoinTask;
import java.util.concurrent.RecursiveTask;

import com.weibo.framework.core.counter.Counter;
import com.weibo.framework.core.model.CounterModel;

/**
 * 多线程协调处理类
 * @author fattiger.xiaoyang
 * @date 2016/03/23
 */
public class CounterRecursiveTask extends RecursiveTask<CounterModel> {

	private static final long serialVersionUID = 8934070532627930803L;
	CounterModel counterModel = new CounterModel();
	final File file;
	final Counter counter;
	
	public CounterRecursiveTask(File file, Counter counter) {
		this.file = file;
		this.counter = counter;
	}

	@Override
	public CounterModel compute() {
		long totalLineNo = 0;
        long codeLineNo = 0;
        long blankLineNo = 0;
        long commentLineNo = 0;
		if (file.isFile()) {
			counterModel = counter.getCounter(file);
		} else {
			final File[] children = file.listFiles();
			if (children != null) {
				List<ForkJoinTask<CounterModel>> taskList = new ArrayList<ForkJoinTask<CounterModel>>();
				for (final File codeFile : children) {
					if (codeFile.isFile()) {
				    	counterModel = counter.getCounter(codeFile);
				    	totalLineNo += counterModel.getTotalLineNo();
				        codeLineNo += counterModel.getCodeLineNo();
				        blankLineNo += counterModel.getBlankLineNo();
				        commentLineNo += counterModel.getCommentLineNo();
					} else {
						taskList.add(new CounterRecursiveTask(codeFile, counter));
					}
				}
				for (final ForkJoinTask<CounterModel> task : invokeAll(taskList)) {
					totalLineNo += task.join().getTotalLineNo();
			        codeLineNo += task.join().getCodeLineNo();
			        blankLineNo += task.join().getBlankLineNo();
			        commentLineNo += task.join().getCommentLineNo();
				}
				counterModel.setTotalLineNo(totalLineNo);
				counterModel.setCodeLineNo(codeLineNo);
				counterModel.setBlankLineNo(blankLineNo);
				counterModel.setCommentLineNo(commentLineNo);
			}
		}
		return counterModel;
	}
}
